#pragma once
#include "stdafx.h"
#include "aggr.h"
#include "op.h"
#include "type.h"
#include "window.h"
enum RelToStrOp {
	ISTREAM,
	DSTREAM,
	RSTREAM
};

enum TimeUnit {
	NOTIMEUNIT,
	SECOND,
	MINUTE,
	HOUR,
	DAY
};


enum NODEKIND {
	N_LIST,
	N_CONT_QUERY,
	N_XSTREAM,
	N_SFW_BLOCK,
	N_SELECT_CLAUSE,
	N_REL_VAR,
	N_ATTR_REF,
	N_ATT_REF,
	N_CONST_VAL,
	N_ARITH_EXPR,
	N_AGGR_EXPR,
	N_CONDN,
	N_WINDOW_SPEC,
	N_TIME_SPEC,
	N_REL_SPEC,
	N_STR_SPEC,
	N_ATTR_SPEC,
	N_UNION,
	N_EXCEPT
};

typedef struct node {
	NODEKIND kind;

	union{    
		// Generic list node: 
		struct{
			struct node *curr;
			struct node *next;      
		} LIST;    
		
	
	
	}u;

}NODE;

NODE *newnode(NODEKIND kind);

NODE *list_node(NODE *n);

NODE *prepend(NODE *n, NODE *list);

// CONT_QUERY with a select from where block
NODE *sfw_cont_query_node(NODE *sfw_block, NODE *rel2str_op);

// CONT_QUERY with a binary operator
NODE *bin_cont_query_node(NODE *bin_op, NODE *rel2str_op);

// SFW_BLOCK
NODE *sfw_block_node(NODE *select_clause, NODE *rel_list,
	NODE *cond_list, NODE *group_list);

// XSTREAM
NODE *istream_node();
NODE *dstream_node();
NODE *rstream_node();

// SELECT_CLAUSE
NODE *select_clause_node(bool b_distinct, NODE *proj_term_list);

// REL_VAR
NODE *rel_var_node(char *rel_name, char *var_name, NODE *window_spec);

// ATTR_REF
NODE *attr_ref_node(char *rel_var_name, char *attr_name);

// CONST_VAL
NODE *int_val_node(int ival);
NODE *flt_val_node(float fval);
NODE *str_val_node(char *sval);

// ARITH_EXPR
NODE *arith_expr_node(ArithOp op, NODE *left_expr, NODE *right_expr);		      

// AGGR_EXPR
NODE *aggr_expr_node(AggrFn fn, NODE *attr);

// CONDN
NODE *condn_node(CompOp op, NODE *left_exptr, NODE *right_expr);

// WINDOW_SPEC
NODE *time_win_node(NODE *time_spec);
NODE *row_win_node(int num_rows);
NODE *now_win_node();
NODE *unbounded_win_node();
NODE *part_win_node(NODE *part_win_attr_list, int num_rows);

// TIME_SPEC
NODE *time_spec_node(TimeUnit unit, int len);

// REL_SPEC
NODE *rel_spec_node(char *rel_name, NODE *attr_list);

// STR_SPEC
NODE *str_spec_node(char *str_name, NODE *attr_list);

// ATTR_SPEC
NODE *int_attr_spec_node(char *attr_name);
NODE *float_attr_spec_node(char *attr_name);
NODE *byte_attr_spec_node(char *attr_name);
NODE *char_attr_spec_node(char *attr_name, int len);

// UNION
NODE *union_node (char *left_table, char *right_table);
NODE *except_node (char *left_table, char *right_table);